#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace XFGameFramework.EquipmentSystem
{
    public class CustomEquipmentConfigDataClassGUI : CustomPropertyGUI
    {

        private string current_skill_class_full_name;

        private Type current_skill_class_type;

        private GUIContent classTypeContent;

        public override void OnPropertyGUI(SerializedProperty property)
        {
            EquipmentConfigData currentEquipmentConfigData = property.serializedObject.targetObject as EquipmentConfigData;

            if (currentEquipmentConfigData == null)
                return;

            if (currentEquipmentConfigData.equipmentType == EquipmentType.Asset)
                return;

            GUILayout.Space(10);

            if (current_skill_class_full_name != property.stringValue)
            {
                current_skill_class_type = AssemblyTools.GetType(property.stringValue);
                current_skill_class_full_name = property.stringValue;
            }

            string message = current_skill_class_type == null ? "无" : current_skill_class_type.Name;

            if (current_skill_class_type != null && !string.IsNullOrEmpty(current_skill_class_type.Namespace))
                message = string.Format("{0}({1})", message, current_skill_class_type.Namespace);

            if (classTypeContent == null)
                classTypeContent = new GUIContent(EditorGUIUtility.IconContent("d_cs Script Icon"));

            classTypeContent.text = message;

            GUILayout.BeginHorizontal();
            GUILayout.Space(30);
            GUILayout.Label("装备脚本", GUILayout.Width(147));

            if (EditorGUILayout.DropdownButton(classTypeContent, FocusType.Passive, GUILayout.MinWidth(0)))
            {
                List<MonoScript> scripts = GetAllEquipmentsType();

                GenericMenu generic = new GenericMenu();

                generic.AddItem(new GUIContent("空"), false, () =>
                {
                    property.stringValue = string.Empty;
                    property.serializedObject.ApplyModifiedProperties();
                });

                generic.AddSeparator(string.Empty);

                foreach (var item in scripts)
                {
                    GUIContent content = new GUIContent(EditorGUIUtility.IconContent("d_cs Script Icon"));

                    content.text = item.GetClass().Name;

                    if (!string.IsNullOrEmpty(item.GetClass().Namespace))
                        content.text = string.Format("{0}({1})", content.text, item.GetClass().Namespace);

                    bool isOn = property.stringValue == item.GetClass().FullName;

                    if (isOn)
                    {
                        generic.AddDisabledItem(content, true);
                    }
                    else
                    {
                        generic.AddItem(content, false, () =>
                        {
                            string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(item));

                            if (string.IsNullOrEmpty(guid)) return;

                            property.stringValue = item.GetClass().FullName;

                            SerializedProperty guid_property = property.serializedObject.FindProperty("equipment_class_guid");
                            guid_property.stringValue = guid;

                            property.serializedObject.ApplyModifiedProperties();
                             
                            AssetDatabase.SaveAssets();

                        });
                    }

                }

                generic.ShowAsContext();

                if (scripts.Count == 0)
                {
                    string m = string.Format("未在项目中发现装备脚本,请创建脚本并实现接口{0}用来处理装备逻辑!", typeof(IEquipment).FullName);
                    Debug.LogWarning(m);
                    EditorWindow.focusedWindow.ShowNotification(new GUIContent(m));
                }
            }

            EditorGUI.BeginDisabledGroup(current_skill_class_type == null);

            if (GUILayout.Button("编辑", GUILayout.Width(50)))
            {
                SerializedProperty guid_property = property.serializedObject.FindProperty("equipment_class_guid");

                string guid = GetGUID(guid_property.stringValue, property.stringValue);
                OpenAsset(guid);
            }

            if (GUILayout.Button("选中", GUILayout.Width(50)))
            {
                SerializedProperty guid_property = property.serializedObject.FindProperty("equipment_class_guid");

                string guid = GetGUID(guid_property.stringValue, property.stringValue);

                SelectAsset(guid);
            }

            EditorGUI.EndDisabledGroup();


            GUILayout.EndHorizontal();
        }


        public static List<MonoScript> GetAllEquipmentsType()
        {
            List<MonoScript> states = new List<MonoScript>();

            string[] scripts = AssetDatabase.FindAssets("t:Script");

            foreach (var item in scripts)
            {
                string path = AssetDatabase.GUIDToAssetPath(item);
                MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);

                if (script == null) continue;

                Type type = script.GetClass();

                if (type == null) continue;

                if (type.IsSubclassOf(typeof(Component))) continue;

                if (typeof(IEquipment) == type) continue;

                if (typeof(IEquipment).IsAssignableFrom(type))
                    states.Add(script);
            }

            return states;
        }


        private static string GetGUID(string guid, string class_full_name)
        {
            if (!IsValid(guid) && !string.IsNullOrEmpty(class_full_name))
            {
                string[] paths = AssetDatabase.FindAssets("t:Script");
                foreach (var item in paths)
                {
                    string asset_path = AssetDatabase.GUIDToAssetPath(item);
                    MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(asset_path);
                    if (script != null && script.GetClass() != null && script.GetClass().FullName.Equals(class_full_name))
                    {
                        return item;
                    }
                }
            }

            return guid;
        }


        private static bool IsValid(string guid)
        {
            string asset_path = AssetDatabase.GUIDToAssetPath(guid);
            if (string.IsNullOrEmpty(asset_path)) return false;

            if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(asset_path) == null)
                return false;

            return true;
        }

        public static void OpenAsset(string guid)
        {
            if (string.IsNullOrEmpty(guid)) return;
            string asset_path = AssetDatabase.GUIDToAssetPath(guid);
            if (string.IsNullOrEmpty(asset_path)) return;
            AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath(asset_path, typeof(UnityEngine.Object)));
        }


        public static void SelectAsset(string guid)
        {
            if (string.IsNullOrEmpty(guid)) return;
            string asset_path = AssetDatabase.GUIDToAssetPath(guid);
            if (string.IsNullOrEmpty(asset_path)) return;

            UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(asset_path, typeof(UnityEngine.Object));
            Selection.activeObject = obj;
            EditorGUIUtility.PingObject(obj);
        }

    }


}

#endif
